package com.ansion.utils;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.AppOpsManager;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;

import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.PermissionChecker;

import com.ansion.log.VLog;

import java.lang.reflect.Method;

public class PermissionUtils {
    public static final int SHOW_WHEN_LOCKED = 10020;

    /**
     * 检测应用有没有通知栏权限，只支持>=19的，否则都是true
     *
     * @return
     * @author ____lamer
     * @date 2019.07.02
     */
    public static boolean hasNotificationPermission() {
        return NotificationManagerCompat.from(ResourceUtils
                .getContext()).areNotificationsEnabled();
    }

    /**
     * 悬浮窗权限
     */
    public static boolean hasFloatingWindowPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return Settings.canDrawOverlays(ResourceUtils.getContext());
        }
        return true;
    }

    /**
     * 锁屏显示权限
     *
     * @return // 0 - no permission, 1 - has permission
     */
    public static boolean hasShowOverPermission(Context context) {
        if ("xiaomi".equalsIgnoreCase(Build.BRAND)) {
            return isCustomPermissionGranted(context, SHOW_WHEN_LOCKED);
        } else if ("vivo".equalsIgnoreCase(Build.BRAND)) {
            return getVivoLockStatus(context) != 1;
        }
        return true;
    }

    public static boolean hasBackPopPermission(Context context) {
        if ("xiaomi".equalsIgnoreCase(Build.BRAND)) {
            return isAllowedBackPopPermission(context);
        } else if ("vivo".equalsIgnoreCase(Build.BRAND)) {
            return getvivoBgStartActivityPermissionStatus(context) != 1;
        }
        return true;
    }

    public static boolean hasAudioPermission() {
        return PermissionChecker.PERMISSION_GRANTED
                == PermissionChecker.checkSelfPermission(ResourceUtils.getContext(), Manifest.permission.RECORD_AUDIO);
    }

    public static boolean hasPermission(Context context, String permission) {
        return PermissionChecker.PERMISSION_GRANTED == PermissionChecker.checkSelfPermission(context, permission);
    }

    public static boolean hasPermission(String permission) {
        return PermissionChecker.PERMISSION_GRANTED == PermissionChecker.checkSelfPermission(ResourceUtils.getContext(), permission);
    }

    public static boolean hasCameraPermission(Context context) {
        return PermissionChecker.PERMISSION_GRANTED
                == PermissionChecker.checkSelfPermission(context, "android.permission.CAMERA");
    }

    public static boolean hasFineLocationPermission(Context context) {
        return PermissionChecker.PERMISSION_GRANTED
                == PermissionChecker.checkSelfPermission(context, "android.permission.ACCESS_FINE_LOCATION");
    }

    public static boolean hasMicphonePermission(Context context) {
        return PermissionChecker.PERMISSION_GRANTED
                == PermissionChecker.checkSelfPermission(context, "android.permission.RECORD_AUDIO");
    }

    @SuppressWarnings("JavaReflectionMemberAccess")
    @TargetApi(19)
    public static boolean isCustomPermissionGranted(Context context, int permission) {
        try {
            AppOpsManager mgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
            Method m = AppOpsManager.class.getMethod("checkOpNoThrow", int.class, int.class, String.class);
            int result = (int) m.invoke(mgr, permission, android.os.Process.myUid(), context.getPackageName());
            return result == AppOpsManager.MODE_ALLOWED;
        } catch (Exception x) {
            x.printStackTrace();
        }
        return true;
    }

    /**
     * pop out in background, XIAOMI
     *
     * @param context
     * @return
     */
    public static boolean isAllowedBackPopPermission(Context context) {
        AppOpsManager ops = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        try {
            int op = 10021;
            Method method = ops.getClass().getMethod("checkOpNoThrow", int.class, int.class, String.class);
            Integer result = (Integer) method.invoke(ops, op, android.os.Process.myUid(), context.getPackageName());
            return result == AppOpsManager.MODE_ALLOWED;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Show on Lock IN XIAOMI
     *
     * @param context
     * @return
     */
    public static boolean canXiaoMiShowLockView(Context context) {
        AppOpsManager ops = null;
        ops = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        try {
            int op = 10020; // >= 23
            // ops.checkOpNoThrow(op, uid, packageName)
            Method method = ops.getClass().getMethod("checkOpNoThrow",
                    int.class, int.class, String.class);
            Integer result = (Integer) method.invoke(ops, op, android.os.Process.myUid(), context.getPackageName());
            return result == AppOpsManager.MODE_ALLOWED;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * showOnLockPermision 1 enable 0 unable
     *
     * @param context
     * @return
     */
    public static int getVivoLockStatus(Context context) {
        String packageName = context.getPackageName();
        Uri uri2 = Uri.parse("content://com.vivo.permissionmanager.provider.permission/control_locked_screen_action");
        String selection = "pkgname = ?";
        String[] selectionArgs = new String[]{packageName};
        try {
            Cursor cursor = context
                    .getContentResolver()
                    .query(uri2, null, selection, selectionArgs, null);
            if (cursor != null) {
                if (cursor.moveToFirst()) {
                    int currentmode = cursor.getInt(cursor.getColumnIndexOrThrow("currentstate"));
                    cursor.close();
                    return currentmode;
                } else {
                    cursor.close();
                    return 1;
                }
            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return 1;
    }

    /**
     * pop up view in background  1 unable 0 enable
     *
     * @param context
     * @return
     */
    public static int getvivoBgStartActivityPermissionStatus(Context context) {
        String packageName = context.getPackageName();
        Uri uri2 = Uri.parse("content://com.vivo.permissionmanager.provider.permission/start_bg_activity");
        String selection = "pkgname = ?";
        String[] selectionArgs = new String[]{packageName};
        try {
            Cursor cursor = context
                    .getContentResolver()
                    .query(uri2, null, selection, selectionArgs, null);
            if (cursor != null) {
                if (cursor.moveToFirst()) {
                    int currentmode = cursor.getInt(cursor.getColumnIndexOrThrow("currentstate"));
                    cursor.close();
                    return currentmode;
                } else {
                    cursor.close();
                    return 1;
                }
            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return 1;
    }

    /**
     * Android 14 and above: Some photo and video access permissions
     *
     * @return
     */
    public static boolean hasMediaVisualUserSelectedPermission() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
                && hasPermission(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED)
                && (!hasPermission(Manifest.permission.READ_MEDIA_IMAGES) || !hasPermission(Manifest.permission.READ_MEDIA_VIDEO));
    }

    public static boolean hasVisualUserSelectedAndNoImagesPermission() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
                && hasPermission(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED)
                && !hasPermission(Manifest.permission.READ_MEDIA_IMAGES);
    }

    public static boolean hasVisualUserSelectedAndNoVideoPermission() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
                && hasPermission(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED)
                && !hasPermission(Manifest.permission.READ_MEDIA_VIDEO);
    }

    /**
     * Check for photo and video access permissions
     */
    public static boolean hasFullMediaPermission() {
        boolean granted;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
                && hasPermission(Manifest.permission.READ_MEDIA_IMAGES)
                && hasPermission(Manifest.permission.READ_MEDIA_VIDEO)
        ) {
            // Full photo and video access on Android 13 (API level 33) or higher
            granted = true;
            VLog.d("TAG_PERMISSION_CHECK", " hasMediaPermission Android 13 (API level 33) or higher granted: true");
        } else if (
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
                        hasPermission(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED)
        ) {
            // Partial photo and video access on Android 14 (API level 34) or higher
            granted = true;
            VLog.d("TAG_PERMISSION_CHECK", " hasMediaPermission Android 14 (API level 34) or higher granted: true");
        } else if (hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) {
            // Full access up to Android 12 (API level 32)
            granted = true;
        } else {
            // Access denied
            granted = false;
        }
        VLog.d("TAG_PERMISSION_CHECK", " hasMediaPermission granted:%b", granted);
        return granted;
    }

    /**
     * Check for photo access permissions
     */
    public static boolean hasImagesPermission() {
        boolean granted;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && hasPermission(Manifest.permission.READ_MEDIA_IMAGES)) {
            // Full photo access on Android 13 (API level 33) or higher
            granted = true;
            VLog.d("TAG_PERMISSION_CHECK", " hasImagesPermission Android 13 (API level 33) or higher granted: true");
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
                hasPermission(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED)) {
            // Partial photo access on Android 14 (API level 34) or higher
            granted = true;
            VLog.d("TAG_PERMISSION_CHECK", " hasImagesPermission Android 14 (API level 34) or higher granted: true");
        } else if (hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) {
            // Full access up to Android 12 (API level 32)
            granted = true;
        } else {
            // Access denied
            granted = false;
        }
        VLog.d("TAG_PERMISSION_CHECK", " hasImagesPermission granted:%b", granted);
        return granted;
    }

    /**
     * Check for videos access permissions
     */
    public static boolean hasVideosPermission() {
        boolean granted;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && hasPermission(Manifest.permission.READ_MEDIA_VIDEO)) {
            // Full videos access on Android 13 (API level 33) or higher
            granted = true;
            VLog.d("TAG_PERMISSION_CHECK", " hasVideosPermission Android 13 (API level 33) or higher granted: true");
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
                hasPermission(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED)) {
            // Partial videos access on Android 14 (API level 34) or higher
            granted = true;
            VLog.d("TAG_PERMISSION_CHECK", " hasVideosPermission Android 14 (API level 34) or higher granted: true");
        } else if (hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) {
            // Full access up to Android 12 (API level 32)
            granted = true;
        } else {
            // Access denied
            granted = false;
        }
        VLog.d("TAG_PERMISSION_CHECK", " hasVideosPermission granted:%b", granted);
        return granted;
    }

}
